package com.rogerfan.easy.shiro;

import java.util.Collection;
import java.util.Set;

import org.apache.shiro.cache.Cache;
import org.apache.shiro.cache.CacheException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;

@Component
public class ShiroRedisCache<K, V> implements Cache<K, V> {

	private static Logger logger = LoggerFactory
			.getLogger(ShiroRedisCache.class);
	
	@Autowired
	public RedisTemplate<Object, Object> redistTemplate;

	private String cacheKey = "shiro-cache";

	@Override
	public V get(K key) throws CacheException {
		try {
			if (key == null) {
				return null;
			} else {
				V value = (V) redistTemplate.opsForHash().get(cacheKey, key);
				return value;
			}
		} catch (Throwable t) {
			throw new CacheException(t);
		}

	}

	@Override
	public V put(K key, V value) throws CacheException {
		try {
			redistTemplate.opsForHash().put(cacheKey, key, value);
			return value;
		} catch (Throwable t) {
			throw new CacheException(t);
		}
	}

	@Override
	public V remove(K key) throws CacheException {
		try {
			V previous = get(key);
			redistTemplate.opsForHash().delete(cacheKey, key);
			return previous;
		} catch (Throwable t) {
			throw new CacheException(t);
		}
	}

	@Override
	public void clear() throws CacheException {
		try {
			redistTemplate.delete(cacheKey);
		} catch (Throwable t) {
			throw new CacheException(t);
		}
	}

	@Override
	public int size() {
		try {
			Long longSize = redistTemplate.opsForHash().size(cacheKey);
			return longSize.intValue();
		} catch (Throwable t) {
			throw new CacheException(t);
		}
	}

	@SuppressWarnings("unchecked")
	@Override
	public Set<K> keys() {
		try {
			Set<K> keys = (Set<K>) redistTemplate.opsForHash().keys(cacheKey);
			return keys;
		} catch (Throwable t) {
			throw new CacheException(t);
		}
	}

	@Override
	public Collection<V> values() {
		try {
			Collection<V> values = (Collection<V>) redistTemplate.opsForHash()
					.values(cacheKey);
			return values;
		} catch (Throwable t) {
			throw new CacheException(t);
		}
	}

}